#include "ClientModel.h"

ClientModel::ClientModel(void)
{
  pointBufferSize = 1024;
  lineBufferSize = 1024;
  pointCount = 0;
  lineCount = 0;
  pointBuffer = new Vertex[pointBufferSize];
  lineBuffer = new Vertex[lineBufferSize * 2];
}

void ClientModel::Eradicate(void)
{
  if(pointBuffer != NULL)
  {
    delete [] pointBuffer;
    pointBuffer = NULL;
  }

  if(lineBuffer != NULL)
  {
    delete [] lineBuffer;
    lineBuffer = NULL;
  }

  while(mObjects.size() > 0)
  {
    GameObject* obj = mObjects.front();
    mObjects.pop_front();
    delete obj;
  }
}
void ClientModel::Reset(void)
{
  Eradicate();
  pointBuffer = new Vertex[pointBufferSize];
  lineBuffer = new Vertex[lineBufferSize * 2];
}
ClientModel::~ClientModel()
{
  Eradicate();
}

GameObject* ClientModel::GetPlayerObject(void)
{
  return localPlayer;
}

GameObject* ClientModel::GetObjectByID(int id)
{
  std::list<GameObject*>::iterator iter;
  iter = mObjects.begin();
  while(iter != mObjects.end())
  {
    if((*iter)->GetID() == id)
      return *iter;
	++iter;
  }
  return NULL;
}

void ClientModel::DestroyObject(int objectID)
{
  std::list<GameObject*>::iterator iter;
  iter = std::remove_if(mObjects.begin(), mObjects.end(), 
	                    std::bind2nd(GameObjectFinder(), objectID));

  mObjects.erase(iter);
}

void ClientModel::AddNewObject(GameObject* obj, clientObjectType oType)
{
  if(oType == clientObjectType::C_PLAYERSPRITE)
    localPlayer = obj;
  mObjects.push_back(obj);
}

void ClientModel::UpdateObjects(void)
{
  std::list<GameObject*>::iterator objIter;
  pointCount = 0;
  lineCount = 0;

  for(objIter = mObjects.begin(); objIter != mObjects.end(); ++objIter)
  {
    GameObject* cur = (GameObject*)*objIter;
    assert(cur != NULL);
    cur->ProcessMessages();
    cur->Update();
    if(cur->IsDead())
    {
	  Message* msg = new Message(MessageType::GAME_OBJECT_ACTION, MessageContent::DESTROY_OBJECT, (void*)cur);
      controller->PassMessage(msg);
    }
    else
    {
	    IRenderable* renderable = cur->GetRenderable();
      if(renderable != NULL)
	    {
        Message* msg = new Message(MessageType::GAME_OBJECT_ACTION, 
                                   MessageContent::SHOULD_RENDER,
                                   (void*)renderable);
        controller->PassMessage(msg);
      }

      Mobile* mobile = cur->GetMobile();
      if(mobile != NULL)
      {
        Message* msg = new Message(MessageType::GAME_OBJECT_ACTION,
                                   MessageContent::DO_PHYSICS,
                                   (void*)mobile);
        controller->PassMessage(msg);
      }
    }
  }
}

Mobile* ClientModel::GetNextMobile(bool resetIterator)
{
  if(resetIterator)
  {
    mobileIterator = mObjects.begin();
  }
  else if(mobileIterator == mObjects.end())
  {
    return NULL;
  }
  Mobile* returnValue = NULL;
  while(true)
  {
    if(mobileIterator == mObjects.end())
    {
      return NULL;
    }
    else if((returnValue = ((GameObject*)*mobileIterator)->GetMobile()) != NULL)
    {
      break;
    }
    ++mobileIterator;
  }
  return returnValue;
}

std::list<GameObject*>* ClientModel::GetAllGameObjects(void)
{
  return &mObjects;
}

